import time
from collections import namedtuple
from typing import Any, List, Tuple, Optional, Union
import os
from datetime import time as datetime_time
from datetime import timedelta
import random

from celery.app.base import Celery


def get_user_settings(fields: List[str]) -> List[str]:
    """ Получаем пользовательские настройки из файла user_data/settings.py """

    user_settings: List[str] = []
    path_to_file: str = os.path.abspath('user_data/settings.txt')

    if not os.path.exists(path_to_file):
        raise ValueError('Не найдено файла user_data/settings.txt')

    with open(path_to_file) as file:
        file_content = file.read().strip()
        file_content = file_content.split(
        '-----------------------------'
        )[1].strip()

    for line in file_content.split('\n\n'):
        name, value = line.split('\n')
        if name in fields: user_settings.append(value)

    return user_settings

def get_parsing_time() -> List[int]:
    """ Получаем время парсинга """

    parsing_time: List[str] = get_user_settings(
        ['start_of_parsing', 'end_of_parsing']
    )
    parsing_time: List[int] = list(map(int, parsing_time))
    return parsing_time

def run_necessary_task(app: Celery) -> None:
    """ Запускаем необходимые задачи """

    start_of_parsing, end_of_parsing = get_parsing_time()
    app.conf.beat_schedule = {
        'track-appearance-sheepments': {
            'task': 'celery_app.track_appearance_sheepments',
            'schedule': timedelta(minutes=1),
            'options': {
                'time_start': datetime_time(start_of_parsing, 0, 0),
                'time_end': datetime_time(end_of_parsing, 0, 0),
            }
        },
    }


def get_links_for_parsing() -> List[str]:
    """ Получаем ссылки для парсинга """

    links_for_parsing: List[str] = []
    path_to_file: str = os.path.abspath('user_data/list_of_links_for_parsing.txt')

    if not os.path.exists(path_to_file):
        message: str = 'Не найдено файла user_data/list_of_links_for_parsing.txt'
        raise ValueError(message)

    with open(path_to_file) as file:
        file_content: str = file.read().strip()

        for line in file_content.split('\n'):
            link: str = line.strip()
            links_for_parsing.append(link)

    return links_for_parsing


def get_list_of_accounts_to_authorization() -> List[Tuple[str, str]]:
    """ Получаем список аккаунтов для авторизации """

    Account: namedtuple = namedtuple('Account', ['login', 'password'])
    list_of_accounts_to_authorization: List[Account] = []

    path_to_file: str = os.path.abspath('user_data/list_of_accounts.txt')

    if not os.path.exists(path_to_file):
        message: str = 'Не найдено файла user_data/list_of_accounts.txt'
        raise ValueError(message)

    with open(path_to_file) as file:
        file_content: str = file.read().strip()

        for account in file_content.split('\n\n'):
            account = Account(
                login=account.split('\n')[0],
                password=account.split('\n')[1]
            )
            list_of_accounts_to_authorization.append(account)

    return list_of_accounts_to_authorization


def get_random_account(
    previous_account: Optional[Tuple[str, str]]
) -> Tuple[str, str]:
    """ Получаем случайный аккаунт """

    list_of_accounts_to_authorization: List[Tuple[str, str]] = \
        get_list_of_accounts_to_authorization()

    if len(list_of_accounts_to_authorization) == 1:
        return list_of_accounts_to_authorization[0]

    while True:
        account: Tuple[str, str] = \
            random.choices(list_of_accounts_to_authorization)[0]

        if not account == previous_account: return account


def wait(
    a: Union[int, float] = 2,
    b: Union[int, float] = 3.5,
    show_message: Optional[bool] = False
) -> None:
    """ Чуть-чуть подождать """

    number = random.uniform(a, b)
    if show_message: print(f'Ждем {number}\n')
    time.sleep(number)
